package com.zzedu.framework.web.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zzedu.common.cache.CacheNameEnum;
import com.zzedu.common.constant.Constants;
import com.zzedu.common.core.domain.entity.SysUser;
import com.zzedu.common.enums.CommonEnums;
import com.zzedu.common.exception.user.UserPasswordRetryLimitExceedException;
import com.zzedu.common.utils.MessageUtils;
import com.zzedu.domain.ZzSendMsg;
import com.zzedu.framework.manager.factory.AsyncFactory;
import com.zzedu.framework.web.domain.LoginForm;
import com.zzedu.framework.web.service.CustomPasswordService;
import com.zzedu.mapper.ZzSendMsgMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicInteger;
@Component("smsCodePasswordService")
public class SysSmsPasswordServiceImpl implements CustomPasswordService, ApplicationRunner {
    @Autowired
    private CacheManager cacheManager;

    private Cache loginRecordCache;

    @Value(value = "${user.password.maxRetryCount}")
    private String maxRetryCount;

    @Autowired
    ZzSendMsgMapper zzSendMsgMapper;

    @Override
    public void validate(SysUser user, LoginForm loginForm) {
        String loginName = loginForm.getUsername();
        AtomicInteger retryCount = loginRecordCache.get(loginName, () -> new AtomicInteger(0));
        if (retryCount.incrementAndGet() > Integer.valueOf(maxRetryCount).intValue()) {
            AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.sms.code.retry.limit.exceed", maxRetryCount));
            throw new UserPasswordRetryLimitExceedException(Integer.valueOf(maxRetryCount).intValue());
        }
        //验证码验证
        LambdaQueryWrapper<ZzSendMsg> zzSendMsgLambdaQueryWrapper = Wrappers.lambdaQuery(ZzSendMsg.class);
        zzSendMsgLambdaQueryWrapper.eq(ZzSendMsg::getPhone, loginForm.getUsername());
        zzSendMsgLambdaQueryWrapper.eq(ZzSendMsg::getIsUsed, CommonEnums.NO.getCode());
        zzSendMsgLambdaQueryWrapper.eq(ZzSendMsg::getSmsType, "APP_LOGIN_VERIFICATION_CODE");
        zzSendMsgLambdaQueryWrapper.ge(ZzSendMsg::getExpireAt, LocalDateTime.now());
        zzSendMsgLambdaQueryWrapper.orderByDesc(ZzSendMsg::getId);
        zzSendMsgLambdaQueryWrapper.last("limit 1");
        ZzSendMsg zzSendMsg = zzSendMsgMapper.selectOne(zzSendMsgLambdaQueryWrapper);
        if (null == zzSendMsg) {
            AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, MessageUtils.message("user.sms.code.retry.limit.count", retryCount));
            loginRecordCache.put(loginName, retryCount);
        } else if (!zzSendMsg.getContent().equals(loginForm.getPassword())) {
            AsyncFactory.recordLogininfor(loginName, Constants.LOGIN_FAIL, "验证码错误");
            loginRecordCache.put(loginName, retryCount);
        }
        zzSendMsg.setIsUsed(CommonEnums.YES.getCode());
        zzSendMsgMapper.updateById(zzSendMsg);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
        loginRecordCache = cacheManager.getCache(CacheNameEnum.LOGINRECORDCACHE.getCode());
    }


}

